package ms.jasim.pddl;

import java.util.ArrayList;
import java.util.List;

public class PddlPredicate implements Comparable<PddlPredicate> {
	
	public static final String ASSIGN = "=";
	public static final String AND_DECOMPOSE2 = "and_subgoal2";
	public static final String AND_DECOMPOSE3 = "and_subgoal3";
	public static final String OR_DECOMPOSE2 = "or_subgoal2";
	public static final String OR_DECOMPOSE3 = "or_subgoal3";
	public static final String ORDER = "order";
	public static final String CAN_PROVIDE = "can_provide";
	public static final String CAN_DEPEND_ON = "can_depend_on";
	public static final String CAN_DEPEND_ON_GOAL = "can_depend_on_g";
	public static final String REQUESTS = "requests";
	public static final String WORK_EFFORT = "work_effort";
	public static final String TIME_EFFORT = "work_time";
	public static final String WORK_LOAD_COEFF = "work_load_coeff";
	public static final String SATISFACTION_COEFF = "satisfaction_coeff";
	public static final String WORK_SAT = "work_sat";
	public static final String SATISFIED = "satisfied";
	public static final String ACTOR_BUDGET = "actor_budget";
	public static final String MAX_SATISFACTION_DEGREE = "max_satisfaction_degree";
	public static final String MAX_JOB_AT_HAND = "max_job_at_hand";
	public static final String PR_SATISFIES = "pr_satisfies";
	public static final String PR_PASSES = "pr_passes";
	public static final String AGENT = "agent";
	public static final String TASK = "task";
	
	public static final String NUM_INSTANCE = "#Instance";
	
	private String functor;
	private List<Object> args;
	private boolean negative;

	
	public PddlPredicate() {
		args = new ArrayList<Object>();
	}

	public PddlPredicate(String functor, Object... args) {
		this();
		setFunctor(functor);
		for (Object a: args)
			this.args.add(a);
		
	}
	
	public void setFunctor(String functor) {
		this.functor = functor;
	}

	public String getFunctor() {
		return functor;
	}

	
	public List<Object> getArgs() {
		return args;
	}

	@Override
	public String toString() {
		StringBuilder res = new StringBuilder();
		if (isNegative())
			res.append("(not ");
		res.append('(');
		res.append(functor);
		for (Object arg : args) {
			res.append(' ');
			res.append(arg);
		}
		res.append(')');
		if (isNegative())
			res.append(")");
		return res.toString();
	}

	@SuppressWarnings("unchecked")
	@Override
	public int compareTo(PddlPredicate p) {
		int result = String.CASE_INSENSITIVE_ORDER.compare(functor, p.functor);
		for(int i = 0; result == 0 && i < args.size() && i < p.args.size(); i ++)
			if (args.get(i) instanceof Comparable)
				result = ((Comparable) args.get(i)).compareTo(p.args.get(i));
		return result;
	}

	
	public void setNegative(boolean negative) {
		this.negative = negative;
	}
	
	public boolean isNegative() {
		return negative;
	}
}
